using System;
using System.Threading.Tasks;
using DailyPoetryX.AzureStorage.Models;
using Microsoft.WindowsAzure.Storage.Table;

namespace DailyPoetryX.AzureStorage.Services.Implementations {
    /// <summary>
    /// 表Token缓存。
    /// </summary>
    public class TableTokenCache : ITokenCache {
        /******** 公开变量 ********/

        /******** 私有变量 ********/

        /// <summary>
        /// 表名。
        /// </summary>
        private const string TableName = "TokenCache";

        /// <summary>
        /// 分区键。
        /// </summary>
        private const string PartitionKey = "DefaultPartition";

        /// <summary>
        /// 表存储。
        /// </summary>
        private CloudTable _table;

        /******** 继承方法 ********/

        /// <summary>
        /// 获得token缓存。
        /// </summary>
        /// <param name="token">Token。</param>
        public async Task<string> GetAsync(string token) {
            var tableOperation =
                TableOperation.Retrieve<TableTokenCacheItem>(PartitionKey,
                    token);
            return (await _table.ExecuteAsync(tableOperation)).Result is
                TableTokenCacheItem cacheItem &&
                cacheItem.ExpiresAt > DateTime.Now.Ticks
                    ? cacheItem.Name
                    : null;
        }

        /// <summary>
        /// 设置token的缓存项。
        /// </summary>
        /// <param name="token">Token。</param>
        /// <param name="name">用户名。</param>
        public async Task SetAsync(string token, string name) {
            var cacheItem = new TableTokenCacheItem {
                PartitionKey = PartitionKey,
                RowKey = token,
                Name = name,
                ExpiresAt = DateTime.Now.AddDays(1).Ticks
            };
            var tableOperation = TableOperation.InsertOrReplace(cacheItem);
            await _table.ExecuteAsync(tableOperation);
        }

        /******** 公开方法 ********/

        /// <summary>
        /// 表Token缓存。
        /// </summary>
        /// <param name="accountProvider">Azure存储账户提供者。</param>
        public TableTokenCache(IAzureStorageAccountProvider accountProvider) {
            var tableClient = accountProvider.GetAccount()
                .CreateCloudTableClient();
            _table = tableClient.GetTableReference(TableName);
        }

        /******** 私有方法 ********/
    }
}